#ifndef ODBC_DETAILS_COLUMN_BUFFER_HPP
#define ODBC_DETAILS_COLUMN_BUFFER_HPP

#include "odbc/details/bindable_buffer.hpp"

namespace odbc
{
namespace details
{

/// \ingroup OdbcLibrary
/// \internal
/// \brief
///		It provides functionality specific to column buffers.
/// \param T the type of the value in the associated column.
/// \param Tr the traits type, should be compatible with \link \c odbc::type_traits \endlink class.
template< typename T, typename Tr = type_traits< T> >
class column_buffer: public bindable_buffer< T, Tr>
{
	typedef bindable_buffer< T, Tr> MyBaseT_;
public:
	/// \brief
	///		It initializes the buffer. 
	/// \details
	///		The bind position is set to an invalid value. Initially, the buffer contains a null value.
	column_buffer() 
	{ 
	}

	///	\brief
	///		It initializes the buffer.  
	/// \details
	///		The bind position is set to an invalid value. Initially, the buffer contains a null value.
	/// \param size the size of the buffer to be created. Since the default column buffer implementation refers to 
	///		fixed size types, this parameter is ignored.
	explicit column_buffer( size_type size)
		: MyBaseT_( size)
	{
	}

	/// \brief
	///		It binds the wrapped buffer to the specified statement at the specified position.
	///	\pre
	///		The specified bind position is not \c -1.
	/// \param stat the statement the buffer will be bound to
	/// \param bindPosition the number of the column the buffer will be bound to. It should not be \c -1.
	virtual void bind( statement& stat, SQLUSMALLINT bindPosition)
	{
		assert( bindPosition != SQLUSMALLINT( -1));
		bindPosition_ = bindPosition;
		SQLRETURN bindRetCode = SQLBindCol( 
				bindable_buffer_base::statement_handle( stat),
				bindPosition,
				(SQLSMALLINT)type_traits::odbc_type_id,
				(SQLPOINTER)type_traits::buffer_to_void( buffer_),
				(SQLINTEGER)type_traits::size_of_buffer( buffer_),
				&lengthIndicator_);
		odbc::odbc_error::check_success( bindRetCode, stat);
	}

	/// \warning
	///		This is a column. The column can't put values, it can only get values. This method should not be called for 
	///		columns.
	virtual void set_value( const boost::any& /*val*/)
	{
		assert( false);
	}
};


} // namespace details
} // namespace odbc

#endif // ODBC_DETAILS_COLUMN_BUFFER_HPP
